package com.aplink.generic.xmlparser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.aplink.generic.GenericFragment;
import com.aplink.generic.constant.ColumnSettingConstant;
import com.aplink.generic.constant.MenuConstant;
import com.aplink.generic.pojo.ColumnSetting;
import com.aplink.generic.pojo.controlspec.ValueList;
import com.aplink.generic.pojo.controlspec.menu.MenuItemSpec;
import com.aplink.generic.pojo.controlspec.menu.PopupMenuSpec;

public class ColumnSettingParser {

    public static ArrayList<ColumnSetting> parse(
            final GenericFragment genericFragment, final int xmlFileId) {
        final ColumnSettingParser columnSettingParser = new ColumnSettingParser();
        return columnSettingParser.parserIntoColumnSetting(xmlFileId,
                ColumnSettingConstant.COLUMN);
    }

    private String getTextNodeValue(final Node node) {
        Node child;
        if (node != null) {
            if (node.hasChildNodes()) {
                child = node.getFirstChild();
                while (child != null) {
                    if (child.getNodeType() == Node.TEXT_NODE) {
                        return child.getNodeValue();
                    }
                    child = child.getNextSibling();
                }
            }
        }
        return "";
    }

    private PopupMenuSpec parsePopupMenuFormat(Node nodeFormat) {
        Element elementFormat = (Element) nodeFormat;
        if (elementFormat.hasChildNodes()) {
            final PopupMenuSpec popupMenuFormat = new PopupMenuSpec();
            NodeList nodeListFormat = elementFormat
                    .getElementsByTagName(MenuConstant.POPUP_MENU);
            if (nodeListFormat.getLength() == 0) {
                return null;
            }
            nodeFormat = nodeListFormat.item(0);
            if (nodeFormat.hasAttributes()) {
                final String controlId = XMLPaserUtil.getAttrValue(nodeFormat,
                        MenuConstant.ID);
                popupMenuFormat.setControlId(controlId);
            }
            if (nodeFormat.getNodeType() == Node.ELEMENT_NODE) {
                elementFormat = (Element) nodeFormat;
                nodeListFormat = elementFormat
                        .getElementsByTagName(MenuConstant.SUB_MENU);
                for (int i = 0; i < nodeListFormat.getLength(); i++) {
                    final Node nodeItem = nodeListFormat.item(i);
                    final MenuItemSpec popupMenuItem = MenuItemParser
                            .parseMenuItemSpec(nodeItem);
                    popupMenuFormat.add(popupMenuItem);
                }
            }
            return popupMenuFormat;
        }
        return null;
    }

    private ArrayList<ColumnSetting> parserIntoColumnSetting(
            final int xmlFileName, final String tagname) {
        try {
            final Document document = XMLPaserUtil
                    .openDocumentFrom(xmlFileName);
            return parseXML(document, tagname);
        } catch (final ParserConfigurationException e) {
            e.printStackTrace();
        } catch (final SAXException e) {
            e.printStackTrace();
        } catch (final IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private ValueList parseValueList(Node nodeFormat) {
        Element elementFormat = (Element) nodeFormat;
        final ValueList valueList = new ValueList();
        if (elementFormat.hasChildNodes()) {
            NodeList nodeListFormat = elementFormat
                    .getElementsByTagName(ColumnSettingConstant.VALUE_LIST);

            if (nodeListFormat.getLength() > 0) {
                nodeFormat = nodeListFormat.item(0);
                if (nodeFormat.hasAttributes()) {
                    final String defaultValue = XMLPaserUtil
                            .getAttrValue(nodeFormat,
                                    ColumnSettingConstant.DEFAULT_VALUE_KEY);
                    if (!defaultValue.isEmpty()) {
                        valueList.setDefaultValue(defaultValue);
                    }
                }

                if (nodeFormat.getNodeType() == Node.ELEMENT_NODE) {
                    elementFormat = (Element) nodeFormat;
                    nodeListFormat = elementFormat
                            .getElementsByTagName(ColumnSettingConstant.VALUE);
                    for (int i = 0; i < nodeListFormat.getLength(); i++) {
                        final Node nodeItem = nodeListFormat.item(i);
                        String display = null;
                        if (nodeItem.hasAttributes()) {
                            display = XMLPaserUtil.getAttrValue(nodeItem,
                                    ColumnSettingConstant.DISPLAY);
                        }
                        final String nodeValue = XMLPaserUtil
                                .getNodeValue(nodeItem);
                        if ((display != null) && (nodeValue != null)) {
                            valueList.put(
                                    nodeValue.toUpperCase(Locale.getDefault()),
                                    display);
                        }
                    }
                }
            }
        }
        return valueList;
    }

    private ArrayList<ColumnSetting> parseXML(final Document doc,
            final String tagname) {
        final ArrayList<ColumnSetting> columnSettingList = new ArrayList<ColumnSetting>();
        final NodeList nList = doc.getElementsByTagName(tagname);
        for (int temp = 0; temp < nList.getLength(); temp++) {
            final Node nNode = nList.item(temp);
            final ColumnSetting columnsetting = new ColumnSetting();
            // set column type
            if (nNode.hasAttributes()) {
                final String colType = XMLPaserUtil.getAttrValue(nNode,
                        ColumnSettingConstant.TYPE);
                if (colType != null) {
                    columnsetting.setColType(colType);
                }

                final String colFormat = XMLPaserUtil.getAttrValue(nNode,
                        ColumnSettingConstant.FORMAT);
                if (colFormat != null) {
                    columnsetting.setFormat(colFormat);
                }

                final String dataobj = XMLPaserUtil.getAttrValue(nNode,
                        ColumnSettingConstant.DATA_OBJ);
                if (dataobj != null) {
                    columnsetting.setDataObj(dataobj);
                }
            }
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                final Element element = (Element) nNode;

                // set mapping name
                NodeList nodes = element
                        .getElementsByTagName(ColumnSettingConstant.MAPPINGNAME);
                if (nodes.getLength() != 0) {
                    final Node node = nodes.item(0);
                    if (node.hasAttributes()) {
                        final String isStaticReource = XMLPaserUtil
                                .getAttrValue(node,
                                        ColumnSettingConstant.STATIC_RESOURCE);
                        if (isStaticReource.equalsIgnoreCase("Y")) {
                            columnsetting.setStaicResource(true);
                        }
                    } else {
                        columnsetting.setMappingName(getTextNodeValue(node));
                    }
                }

                // set linking mapping name
                nodes = element
                        .getElementsByTagName(ColumnSettingConstant.LINKINGMAPPINGNAME);
                if (nodes.getLength() != 0) {
                    columnsetting.setLinkMappingName(getTextNodeValue(nodes
                            .item(0)));
                }

                // set linkpage
                nodes = element
                        .getElementsByTagName(ColumnSettingConstant.LINKPAGE);
                if (nodes.getLength() != 0) {
                    columnsetting.setLinkPage(getTextNodeValue(nodes.item(0)));
                }

                // set header
                nodes = element
                        .getElementsByTagName(ColumnSettingConstant.HEADER);
                if (nodes.getLength() != 0) {
                    columnsetting
                            .setHeaderText(getTextNodeValue(nodes.item(0)));
                }

                final PopupMenuSpec popupMenuSpec = parsePopupMenuFormat(nNode);
                if (popupMenuSpec != null) {
                    popupMenuSpec.setActiveControl(columnsetting
                            .getLinkMappingName());
                    columnsetting.setPopupMenuSpec(popupMenuSpec);
                }

                final ValueList valueList = parseValueList(nNode);
                if (valueList != null) {
                    columnsetting.setValueList(valueList);
                }
            }
            columnSettingList.add(columnsetting);
        }
        return columnSettingList;
    }
}
